﻿// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Threading.Tasks;

namespace Microsoft.SemanticKernel.Planning.Handlebars;

/// <summary>
/// Configuration for Handlebars planner instances.
/// </summary>
public sealed class HandlebarsPlannerOptions : PlannerOptions
{
    /// <summary>
    /// The prompt execution settings to use for the planner.
    /// </summary>
    public PromptExecutionSettings? ExecutionSettings { get; set; }

    /// <summary>
    /// Delegate to get additional context for the prompt.
    /// </summary>
    /// <remarks>
    /// Additional context can be any domain knowledge or specific content that might help the model better fulfill the goal.
    /// This context should just hold static information that's the same for every request. It should not include variables; use KernelArguments when invoking the planner instead.
    /// </remarks>
    public Func<Task<string>>? GetAdditionalPromptContext { get; set; }

    /// <summary>
    /// Delegate that returns an override for the CreatePlan prompt.
    /// </summary>
    /// <remarks>
    /// Handler will be used as a callback. The callback should return a valid Handlebars template string in a ```handlebars codeblock.
    /// If this is set, the planner will use this prompt instead of the default prompt.
    /// Devs can select any partial defined in Planners.Handlebars.CreatePlanPromptPartials namespace when constructing their own prompt.
    /// No partials are included by default; make sure to select partials such as "{{> UserGoal }}" or {{> AdditionalContext}} if needed.
    /// </remarks>
    public Func<string>? CreatePlanPromptHandler { get; set; }

    /// <summary>
    /// Gets or sets the last plan generated by the planner.
    /// </summary>
    public HandlebarsPlan? LastPlan { get; set; }

    /// <summary>
    /// Gets or sets the last error that occurred during planning.
    /// </summary>
    public string? LastError { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether loops are allowed in the plan.
    /// </summary>
    public bool AllowLoops { get; set; } = true;

    /// <summary>
    /// Initializes a new instance of the <see cref="HandlebarsPlannerOptions"/> class.
    /// </summary>
    public HandlebarsPlannerOptions(
        HandlebarsPlan? lastPlan = default,
        string? lastError = default,
        bool allowLoops = true
    )
    {
        this.LastPlan = lastPlan;
        this.LastError = lastError;
        this.AllowLoops = allowLoops;
    }
}
